'''
Description: description
Author: 
LastEditors: M
'''
import time,queue
from threading import Thread

import compoments.utils as U
import compoments.config as CFG
from compoments.sys_info import SYS_STATISTIC
from compoments.task import T_task


class TaskCollection():
    task_q:queue.Queue=None
    def __init__(self) -> None:
        self.task_q = queue.Queue(maxsize=CFG.MAX_TASK_CNT)
    def append_task(self,task):
        """
        @params p_from:配置来自哪儿
        @params p_to:配置文件用在哪儿
        """
        if self.task_q.full():
            print("quene FULL")
            return False 
        self.task_q.put(task)
        return True
    def get_a_task(self):
        """
        如果当前不存在 返回None
        """
        if self.task_q.empty():
            return None 
        #TODO 暂时 不考虑并发
        task = self.task_q.get_nowait()
        self.task_q.task_done()
        return task
    def __len__(self):
        return self.task_q.qsize()
    def empty(self): 
        return self.task_q.empty()

def assign_task(cts:TaskCollection):
    MANAGE_ADJUST_INTERBAL = 2

    sstatic = SYS_STATISTIC()
    sstatic.start_statistic()
    U.print_with_time(U._warning_("ready for running task..."))
    
    time.sleep(CFG.COOL_TIME)
    while True:
        if sstatic.READY:
            break
        time.sleep(1)

    task_pool={}
    start_cpu_avg_rate,start_mem_avg_rate =sstatic.get_now_cpu_and_mem_rate()
    

    task_group_name = time.strftime("%m-%d%H-%M-%S", time.localtime())
    def start_a_task():
    #第一个任务县启动估算一下 任务暂用的计算量
        cur_task:T_task = cts.get_a_task()
        if cur_task is None:
            return
        cur_task_t = Thread(target=cur_task.load_params_and_run,args=(task_group_name,))
        cur_task_t.setDaemon(True)
        cur_task_t.start()
        task_name = f"{int(time.time())}-{cur_task_t.getName()}"
        task_pool[task_name] = cur_task_t
    last_task_start_time = int(time.time())
    
    start_a_task()

    time.sleep(CFG.PROCESS_INTERVAL)


    first_task_cpu_used,first_task_mem_used = sstatic.delta_to(start_cpu_avg_rate,start_mem_avg_rate)

    try:
        while True:
            time.sleep(MANAGE_ADJUST_INTERBAL)
            print(".",end="")
            task_done =list()
            for _tname,_task in task_pool.items():
                if not _task.isAlive():
                    task_pool[_tname].join()
                    task_done.append(_tname)
                    U.print_with_time("\n完成任务:",U._ok_(_tname))
            for dt in task_done:
                del task_pool[dt]
            if len(task_pool)==0 and cts.empty():
                break
            if len(task_pool)>=CFG.PARALLEL_CNT:
                continue
            if  (int(time.time())-last_task_start_time)>CFG.PROCESS_INTERVAL:
                #有启动间隔且有任务待启动
                #统计平均
                delta_cpu,delta_mem = sstatic.delta_to(start_cpu_avg_rate,start_mem_avg_rate) 
                
                task_running_cnt = len(task_pool)
                now_cpu_remain,now_mem_remain = sstatic.now_remain()                
                if task_running_cnt>0:
                    avg_task_cpu = delta_cpu/task_running_cnt
                    avg_task_mem = delta_mem/task_running_cnt
                    cpu_ok = now_cpu_remain > max(first_task_cpu_used,avg_task_cpu)
                    mem_ok = now_mem_remain > max(first_task_mem_used,avg_task_mem)
                else:
                    #TODO 0个任务的时候 有什么不同吗
                    cpu_ok = True 
                    mem_ok = True 
                if cpu_ok and mem_ok:
                    start_a_task()
                    last_task_start_time = int(time.time())
        sstatic.stop_statistic()
    except Exception as e:
        U.errormsg("piker 任务管理器 出现 异常",emphasis=str(e))
    finally:
        for tn,t in task_pool.items():
            print(f"\t 等待{tn}结束...",end="")
            t.join()
            print(f"\t {tn}已结束")